package org.jim.server.command.handler;

import com.google.common.collect.ImmutableList;
import org.jim.core.ImChannelContext;
import org.jim.core.ImPacket;
import org.jim.core.ImStatus;
import org.jim.core.config.ImConfig;
import org.jim.core.exception.ImException;
import org.jim.core.message.MessageHelper;
import org.jim.core.packets.*;
import org.jim.core.utils.JsonKit;
import org.jim.server.JimServerAPI;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.config.ImServerConfig;
import org.jim.server.processor.group.GroupCmdProcessor;
import org.jim.server.protocol.ProtocolManager;
import org.jim.server.util.ChatKit;
import org.jim.server.util.ImServerKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
 * 版本: [1.0]
 * 功能说明: 群组处理器
 */
public class GroupReqHandler extends AbstractCmdHandler {

    private static final Logger log = LoggerFactory.getLogger(GroupReqHandler.class);

    @Override
    public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
        CreateGroupBody groupBody = JsonKit.toBean(packet.getBody(), CreateGroupBody.class);
        //param error
        if (Objects.isNull(groupBody) || !ImmutableList.of("c", "d", "q", "i").contains(groupBody.getOperType())) {
            return ProtocolManager.Packet.dataInCorrect(Command.COMMAND_GROUP_HANDLE_REQ, ImStatus.C10020, channelContext);
        }
        log.info("GroupReqHandler groupBody:{}", JsonKit.toJSONString(groupBody));
        ImServerConfig imServerConfig = ImConfig.Global.get();
        boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
        MessageHelper messageHelper = imServerConfig.getMessageHelper();
        GroupCmdProcessor processor = getSingleProcessor(GroupCmdProcessor.class);
        User user = ImServerKit.getUser(channelContext);
        GroupResult result = GroupResult.create(ImStatus.C10020);
        if (processor != null) {
            String operType = groupBody.getOperType();
            switch (operType) {
                case "c":
                    result = processor.create(groupBody, channelContext);
                    if (result.getStatus() == ImStatus.C10000) {
                        Group group = result.getGroup();
                        user.getGroups().add(group);
                        JimServerAPI.bindGroup(channelContext, group);
                        group.getUsers().stream().filter(f -> !f.getUserId().equalsIgnoreCase(user.getUserId()))
                                .forEach(fe -> {
                                    messageHelper.addGroupUser(fe.getUserId(), group.getGroupId());
                                    if (ChatKit.isOnline(fe.getUserId(), isStore)) {
                                        JimServerAPI.bindGroup(channelContext, fe.getUserId(), group.getGroupId());
                                    }
                                });
                    }
                    break;
                case "d":
                    result = processor.disband(groupBody, channelContext);
                    if (result.getStatus() == ImStatus.C10000) {
                        Group group = result.getGroup();
                        JimServerAPI.unbindGroup(group.getGroupId(), channelContext);
                        group.getUsers().stream().filter(f -> !f.getUserId().equalsIgnoreCase(user.getUserId()))
                                .forEach(fe -> {
                                            messageHelper.removeGroupUser(fe.getUserId(), group.getGroupId());
                                            if (ChatKit.isOnline(fe.getUserId(), isStore)) {
                                                JimServerAPI.unbindGroup(fe.getUserId(), group.getGroupId());
                                            }
                                        }
                                );
                    }
                    break;
                case "q":
                    result = processor.quit(groupBody, channelContext);
                    if (result.getStatus() == ImStatus.C10000) {
                        Group group = result.getGroup();
                        messageHelper.removeGroupUser(group.getGroupId(), user.getUserId());
                        JimServerAPI.unbindGroup(group.getGroupId(), channelContext);
                    }
                    break;
                case "i":
                    result = processor.invite(groupBody, channelContext);
                    if (result.getStatus() == ImStatus.C10000) {
                        Group group = result.getGroup();
                        messageHelper.addGroupUser(groupBody.getUserId(), group.getGroupId());
                        if (ChatKit.isOnline(groupBody.getUserId(), isStore)) {
                            JimServerAPI.bindGroup(channelContext, groupBody.getUserId(), group.getGroupId());
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        if (result.getStatus() == ImStatus.C10000) {
            Group group = result.getGroup();
            for (User _user : group.getUsers()) {
                String userId = _user.getUserId();
                if (!ChatKit.isOnline(userId, isStore)) {
                    messageHelper.cacheUserIfPresent(_user);
                    continue;
                }
                ImPacket imPacket = new ImPacket(Command.COMMAND_GROUP_HANDLE_RESP, new RespBody(Command.COMMAND_GROUP_HANDLE_RESP,
                        ImStatus.C10026).toByte());
                imPacket.setSynSeq(packet.getSynSeq());
                JimServerAPI.sendToUser(userId, imPacket);
            }
            return ProtocolManager.Converter.respPacket(new RespBody(Command.COMMAND_GROUP_HANDLE_RESP, ImStatus.C10000), channelContext);
        } else {
            return ProtocolManager.Packet.dataInCorrect(Command.COMMAND_GROUP_HANDLE_RESP, result.getStatus(), channelContext);
        }
    }

    @Override
    public Command command() {
        return Command.COMMAND_GROUP_HANDLE_REQ;
    }
}
